/**
 * @documents form https://jsonform.github.io/jsonform/playground/index.html?example=templating-idx
 * @documents validate http://fabian-kostadinov.github.io/2014/09/22/validation-in-jsonform/
 * depend
 * jQuery
 * jQuery from
 */
// ReuestJs.js
// JiraClient.js
// JiraStatus.js
class MaintenanceTicket
{
    constructor(config)
    {
        this.formSchema = {};
        this.formDefaultValuesConditions = {};
        this.targetJira = new JiraClient(config.target);
        this.sourceJira = new JiraClient(config.source);
        this.jiraStatus = new JiraStatus();
        this.issueObject = null;
        this.Init();
    }

    async getTicketData(issueKeyOrId)
    {
        try {
            let promise = await this.targetJira.getIssue(issueKeyOrId);

            if (promise.status==200) {
                this.issueObject = await promise.json();
            }
        } catch (e) {
            alert(e);
            console.error('##Get Ticket Data Exception', e);
        }
    }

    renderStatus(status)
    {
        let html = `
<p>
    <strong class="name" style="color: blue;">HP Status:</strong>
    <span style="color: red;font-weight: bold;">{{status}}</span>
</p>
        `;

        jQuery('.status-view').after(html.replace('{{status}}', status));
    }

    renderSyncButton()
    {
        let self = this;
        let html = `
<div id="sync-status" class="aui-buttons pluggable-ops">
    <a class="aui-button toolbar-trigger" href="javascript:void(0)" style="color:blue;">
        <span class="trigger-label">Sync Status</span>
    </a>
</div>
        `;

        jQuery('.aui-toolbar2-inner').append(html);

        // bundle
        jQuery('#sync-status a').on('click', (e) => {
            self.renderPopup();
            // get tickets render data
            this.renderForm();
            jQuery('#sync-ticket-status').show();
        });
    }

    renderPopup()
    {
		let layout = `
        <style>#sync-issue-form-container span.help-block{color:orangered;}</style>
        <section id="sync-issue-dialog" class="aui-dialog2 aui-layer jira-dialog2 jira-dialog-core aui-dialog2-large jira-dialog-open jira-dialog-content-ready" role="dialog" aria-labelledby="jira-dialog2__heading" style="z-index: 3000;" data-aui-focus="false" data-aui-blanketed="true" open="" tabindex="-1">
        <header class="aui-dialog2-header jira-dialog-core-heading">
        <h2 id="jira-dialog2__heading" title="Record Time">{{title}}</h2>
        </header>
        <div class="aui-dialog2-content jira-dialog-core-content">
        <div class="qf-container">
        <div class="form-footer">
        <div class="dialog-error">
        <div id="sync-issue-form-container"><form class="aui"></form></div>
        </div>
        </div>
        </div>
        </div>
        <footer class="aui-dialog2-footer">
        <div class="buttons-container form-footer">
        <div class="buttons">
        <span class="throbber"></span>
        <input class="button aui-button aui-button-primary" id="sync-ticket-status" style="display:none;" name="Save" type="submit" value="Save">
        <button class="aui-button aui-button-link cancel" id="aui-dialog-close" resolved="">Close</button>
        </div></div></footer></section>
        <div id="jira-bg-mark" aria-hidden="true" class="aui-blanket" tabindex="0" style="z-index: 2980;"></div>
`;
        // title
        layout = layout.replace('{{title}}', jQuery('#summary-val').text());

        jQuery('#sync-issue-dialog').remove();
        jQuery('body').append(layout);
        jQuery('#jira-bg-mark').on('click', (e) => {
            jQuery('#sync-issue-dialog').remove();
            jQuery('#jira-bg-mark').remove();
        });
        jQuery('#aui-dialog-close').on('click', (e) => {
            jQuery('#sync-issue-dialog').remove();
            jQuery('#jira-bg-mark').remove();
        });
    }

    setFormDefaultValues(issueObject)
    {
        this.formSchema;
    }

    renderForm()
    {
        let self = this;
        this.setFormDefaultValues(this.issueObject);

        let options = this.formSchema;
        options.onSubmit = function (errors, values) {
            let keys = Object.keys(values.fields);
            keys.forEach((key) => {
                console.log('#item', '[name="fields.' + key + '"]');
                if (jQuery('[name="fields.' + key + '"]').attr('multiple')=='multiple') {
                    let _values = [];
                    jQuery('[name="fields.' + key + '"] option:selected').each((idx, ele) => {
                        _values.push({"value":jQuery(ele).val()});
                    });
                    if (values.hasOwnProperty('fields') && values.fields.hasOwnProperty(key)) {
                        values.fields[key] = _values;
                    }
                }
            });
            console.log('#values ready', values);
            console.log('#options', options);

            if (options.hasOwnProperty('onSubmitValid')) {
                if (!options.onSubmitValid(values)) {
                    throw new Error("input values error!", values);
                }
            }

            // submit to jira
            self.jiraSync(values);
        }

        console.log('#options', options);

        jQuery('#sync-issue-form-container form').jsonForm(options);
        jQuery('#sync-ticket-status').on('click', (e) => {
            // submit form
            if ('[object Undefined]' != Object.prototype.toString.call(loadingDiv)) {
                jQuery('#sync-ticket-status').after(loadingDiv);
            }
            jQuery('#sync-issue-form-container form').trigger('submit');
        });
    }

    async jiraSync(issueUpdateObject)
    {
        // get status, and remove from payload
        let finalStatus = issueUpdateObject.fields.status.name;
        let comment = issueUpdateObject.fields.comment;
        // remove status form fields
        delete issueUpdateObject.fields.status;
        delete issueUpdateObject.fields.comment;

        let result = [];

        // target issueKey
        //let targetIssueKey = jQuery('#customfieldmodule .property-list div.value:eq(0)').text().trim().toLocaleUpperCase();
        // update fields
        let fResp = await this.targetJira.updateIssue(this.issueObject.key, issueUpdateObject);
        if (fResp.status!=204) {
            result.push({'issue':this.issueObject.key,'error': await fResp.json()});
        }

        // update status
        let isWoc = finalStatus.trim().toLocaleUpperCase()==='Waiting on Customer'.trim().toLocaleUpperCase() ? true : false;
        // 1. source
        let sourceIssueKey = jQuery('#key-val').data('issue-key').toLocaleUpperCase();
        if (isWoc) {
            // only add Labels
            await this.sourceJira.updateIssue(sourceIssueKey, {"fields": {"labels":["WOC"]}});
        } else {
            // update status
            let type = jQuery('#type-val').text().trim().toLocaleUpperCase();
            this.jiraStatus.jiraClient = this.sourceJira;
            if (type=='BUG') {
                // source bug workflow
                this.jiraStatus.workflow = sBugWorkflow;
                await this.jiraStatus.updateTransition(sourceIssueKey, finalStatus);
            } else {
                this.jiraStatus.workflow = sTaskWorkflow;
                await this.jiraStatus.updateTransition(sourceIssueKey, finalStatus);
            }
        }

        // 2. target
        let type = this.issueObject.fields.issuetype.name.toLocaleUpperCase();
        this.jiraStatus.jiraClient = this.targetJira;
        if (type=='BUG') {
            // source bug workflow
            this.jiraStatus.workflow = tBugWorkflow;
            await this.jiraStatus.updateTransition(this.issueObject.key, finalStatus);
        } else {
            this.jiraStatus.workflow = tTaskWorkflow;
            await this.jiraStatus.updateTransition(this.issueObject.key, finalStatus);
        }

        // add comment
        if (isWoc && comment) {
            await this.targetJira.addComment(this.issueObject.key, '[~' + this.issueObject.fields.reporter.name + '] ' + comment);
        }

        // refresh page
        location.reload();
    }

    async Init()
    {
        let  regex = /^HPST-\d+/;
        let title = jQuery('#summary-val').html().match(regex);
        if (title) {
            let issueKeyOrId = title[0];
            await this.getTicketData(issueKeyOrId);
            this.renderSyncButton();
            // get ticket status
            this.renderStatus(this.issueObject.fields.status.name);
        }
    }
}
